package gui.batches;

import core.Item;
import core.ItemFacade;
import core.exception.ModelException;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.Timer;

import gui.common.*;
import gui.inventory.*;

/**
 * Controller class for the transfer item batch view.
 */
public class TransferItemBatchController extends ItemBatchController implements
		ITransferItemBatchController {
	
	private ProductContainerData _target;
	
	private boolean _usingScanner;
	private boolean _barcodeEmpty;
	
	private Timer barcodeTimer = new Timer(1000,
			new ActionListener() {
				public void actionPerformed(ActionEvent a) {
					transferItem();
				}
			}
	);
	
	/**
	 * Constructor.
	 * 
	 * @param view Reference to the transfer item batch view.
	 * @param target Reference to the storage unit to which items are being transferred.
	 */
	public TransferItemBatchController(IView view, ProductContainerData target) {
		super(view);

		_target = target;
		construct();
	}
	
	/**
	 * Returns a reference to the view for this controller.
	 */
	@Override
	protected ITransferItemBatchView getView() {
		return (ITransferItemBatchView)super.getView();
	}

	/**
	 * Sets the enable/disable state of all components in the controller's view.
	 * A component should be enabled only if the user is currently
	 * allowed to interact with that component.
	 * 
	 * {@pre None}
	 * 
	 * {@post The enable/disable state of all components in the controller's view
	 * have been set appropriately.}
	 */
	@Override
	protected void enableComponents() {
		getView().enableItemAction(!getView().getBarcode().isEmpty());
		getView().enableItemAction(true);
		if (getView().getUseScanner()) {
			getView().enableItemAction(false);
		}
		getView().enableRedo(canRedo());
		getView().enableUndo(canUndo());
	}

	/**
	 * This method is called when the "Item Barcode" field in the
	 * transfer item batch view is changed by the user.
	 */
	@Override
	public void barcodeChanged() {
		_barcodeEmpty = getView().getBarcode().length() == 0;
		if (_usingScanner) {

			if (_barcodeEmpty) {
				barcodeTimer.stop();
			}
			else if (barcodeTimer.isRunning()) {
				barcodeTimer.restart();
			}
			else {
				barcodeTimer.start();
			}
			
		}
		enableComponents();
	}
	
	/**
	 * This method is called when the "Use Barcode Scanner" setting in the
	 * transfer item batch view is changed by the user.
	 */
	@Override
	public void useScannerChanged() {
		_usingScanner = getView().getUseScanner();
		if (!(getView().getBarcode().isEmpty()) && _usingScanner) {
			barcodeTimer.start();
		}
		else if (!_usingScanner) {
			barcodeTimer.stop();
		}
		enableComponents();
	}
	
	/**
	 * This method is called when the user clicks the "Transfer Item" button
	 * in the transfer item batch view.
	 */
	@Override
	public void transferItem() {
		try {
			Item toTransfer = ItemFacade.instance().getItem(getView().getBarcode());
			if (!ItemFacade.instance().canTransferItem(toTransfer, _target.getContainer()))
				getView().displayErrorMessage("The item is already in the target storage unit");
			else{
				TransferItemCommand command = new TransferItemCommand(
						toTransfer,toTransfer.getContainer().getStorageUnit(), 
						_target.getContainer());
				doCommand(command);
			}
		} catch (ModelException e) {
			getView().displayErrorMessage(e.getMessage());
		}
		loadValues();
		getView().setBarcode("");
		getView().giveBarcodeFocus();
		enableComponents();
		
		barcodeTimer.stop();
	}

	/**
	 * This method is called when the user clicks the "Done" button
	 * in the transfer item batch view.
	 */
	@Override
	public void done() {
		getView().close();
		onDone();
	}

}

